package com.springboot.middleware.middleware_redisson.server.rabbitmq;

import com.springboot.middleware.middleware_redisson.server.dto.DeadDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.AbstractJavaTypeMapper;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * 死信队列基本模型 - 生产者
 */
@Component
public class MqDelayQueuePublisher {
    private static final Logger log = LoggerFactory.getLogger(MqDelayQueuePublisher.class);

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Value("${mq.redisson.dead.basic.exchange.name}")
    private String basicExchangeName;
    @Value("${mq.redisson.dead.basic.routing.key}")
    private String basicRoutingKey;

    /**
     * 发送消息入死信队列
     *
     * @param msg 消息
     * @param ttl 过期时间
     */
    public void sendDelayMsg(final DeadDto msg, final Long ttl) {
        try {
            //设置传输格式
            rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
            //设置死信路由, 死信交换机
            rabbitTemplate.setExchange(basicExchangeName);
            rabbitTemplate.setRoutingKey(basicRoutingKey);
            //调用rabbitMQ组件发送消息
            MessagePostProcessor messagePostProcessor = message -> {
                MessageProperties messageProperties = message.getMessageProperties();
                //设置消息的持久化策略
                messageProperties.setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                //设置指定消息头中消息的具体类型
                messageProperties.setHeader(AbstractJavaTypeMapper.DEFAULT_CONTENT_CLASSID_FIELD_NAME, DeadDto.class);
                //设置消息过期时间
                messageProperties.setExpiration(ttl.toString());
                return message;
            };
            rabbitTemplate.convertAndSend(msg, messagePostProcessor);
            log.info("RabbitMQ死信队列消息模型-生产者-发送消息入延迟队列-消息: {}, ttl:{}", msg, ttl);
        } catch (Exception e) {
            log.error("RabbitMQ死信队列消息模型-生产者-发送消息入延迟队列-发生异常: {}", msg, e.fillInStackTrace());
        }
    }
}
